<html>
	
	<!-- 
			IMPORTANT
			
			To setup the title of the page use find/replace, 
			and replace 'Your Title Here' by the html text of your title
			
			To setup the link which make the page return the the with-frame content
			use find/replace and replace 'YourFileNameHere' by the 
	-->
	
	<head>
		<title>Creating real time particles - Kairos API Documentation</title>
		
		<link rel="stylesheet" href="../../docs/style.css" type="text/css" media="screen" />
		<link rel="stylesheet" href="../../docs/print.css" type="text/css" media="print" />
		
		<script language="javascript" type="text/javascript" src="../../docs/asdoc.js"></script>
		<script language="javascript" type="text/javascript" src="../js/swfobject.js"></script>
		
	</head>
	<body>
		<script type="text/javascript" language="javascript" src="../../../asdoc.js"></script><script type="text/javascript" language="javascript" src="../../../cookies.js"></script><script type="text/javascript" language="javascript">
		<!--
			asdocTitle = 'Creating real time particles - Kairos API Documentation';
			var baseRef = '../../docs/';
			window.onload = configPage;
		--></script>
		
		<table id="titleTable" cellspacing="0" cellpadding="0" class="titleTable">
			<tr>
			
				<td align="left" class="titleTableTitle">Kairos API Documentation</td>
				<td align="right" class="titleTableTopNav">
					<a 	onclick="loadClassListFrame('../../docs/all-classes.html')" 
					   	href="../../docs/package-summary.html">All&nbsp;Packages</a>&nbsp;|&nbsp;
					<a 	onclick="loadClassListFrame('../../docs/all-classes.html')" 
						href="../../docs/class-summary.html">All&nbsp;Classes</a>&nbsp;|&nbsp;
					<a 	onclick="loadClassListFrame('../../docs/index-list.html')" 
						href="../../docs/all-index-A.html">Index</a>&nbsp;|&nbsp;
					<a 	href="../../docs/index.html?howto/particle-tutrial-en.html&amp;class-list.html" id="framesLink1">Frames</a>
					<a 	onclick="parent.location=document.location" 
						href="" 
						style="display:none;" 
						id="noFramesLink1">No&nbsp;Frames</a>
				</td>
				<td rowspan="3" align="right" class="titleTableLogo">
					<img alt="Adobe Logo" title="Adobe Logo" class="logoImage" src="../../docs/images/logo.jpg">
				</td>
			</tr>
			<tr class="titleTableRow2">
				<td align="left" id="subTitle" class="titleTableSubTitle">
					Creating real time particles
				</td>
				<td class="titleTableSubTitle">
					&nbsp;
				</td>			
			</tr>
			<tr class="titleTableRow3">
				<td colspan="2">&nbsp;</td>
			</tr>
		</table
		
		
		<script type="text/javascript" language="javascript">
		<!--
		if (!isEclipse() || window.name != ECLIPSE_FRAME_NAME) 
		{
			titleBar_setSubTitle("Creating real time particles");
			
			titleBar_setSubNav(false,	false,	   false,
							   false,   false,	   false,
							   false,   false,	   false,
							   false,   false,	   false,
							   false,   false
							   );
		}
		--></script>
<div class="MainContent">
	
<p>In this tutorial, we will see how using Kairos in the creation
of a lightweight particle effect, which will be animate in real time.</p>

<h2>Summary</h2>
<ul>
<li><a href="#objectif">Goal of this tutorial</a></li>
<li><a href="#prerequisite">Requirements</a></li>
<li><a href="#concret">The Real Stuff</a>
<ul>
<li><a href="#generation">Particles generation</a></li>

<li><a href="#particles">Particles</a></li>
<li><a href="#animation">Particles motion</a></li>
</ul></li>
<li><a href="#monitoring">Using the monitoring tools</a></li>
<li><a href="#adjust">Last tweaks</a>
<ul>
<li><a href="#motion">Slow ans fast motion effects</a></li>
</ul></li>
</ul>

<hr size="1"/>
<a name="objectif"></a></p>
<h2>Goal of this tutorial</h2>

<p>
	In this tutorial, we will see how using Kairos in the creation
of a lightweight particle effect, which will be animate in real time.
You can see below the result of this tutorial in action. Move
the mouse over the flash to start the motion.
</p>

<div id="flashresult"></div>
		
<script type="text/javascript">
   var so = new SWFObject("../examples/particles/ParticleRTRunner.swf", "result", "500", "130", "9", "#000000");
   so.write("flashresult");
</script>

<p>
	Note : Some parts of this tutorial doesn't always follow the common
developpement good practices, that is done only to focus on the most
important aspects of the real time approach.
</p>

<hr size="1"/>
<a name="prerequisite"></a>
<h2>Requirements</h2>

<p>
	This tutorial is intended for people which already know AS3 basics 
and display list concept. Additionally, as Kairos is an extension to 
the <a href="http://code.google.com/p/lowra" title="Low level Rewrite on Actionscript3">LowRA</a>
framework, a knowledge of the event system of Lowra is needed.
</p>

<p></p>

<hr size="1"/>
<a name="concret"></a>
<h2>The Real Stuff</h2>


<p>
	We will see how to use Kairos to create a simple particle effect, 
running in real time, and how build new objects or utilities 
for real time engine.</p>

<hr size="1"/>
<a name="generation"></a>
<h3>Particules generation</h3>

<p>
	First, we will create our example entry class. That class will
generate the particles and manage their life time. That class extend
the <code>Sprite</code>.
</p><p>
	Created particles will be stored in a <code>Dictionnary</code> object, 
additionally we will put on the stage a transparent button which will 
allow us to start/stop the animation on roll-over/roll-out. That behavior
will be created using the <code>start</code> and <code>stop</code> methods
of our object.
</p><p>
	Particles generation is realized using an <code>IntervalRT</code> object
(you can find it in the <a href="../../docs/com/kairos/commands/package-detail.html">
com.kairos.commands</a> package). The interval object will call back the 
<code>createParticles()</code> method of our runner object.
</p>

<div class="listing"><pre>
package
{
	import com.kairos.commands.IntervalRT;
	import com.bourre.commands.Delegate;
	
	import flash.display.Sprite;
	import flash.utils.Dictionary;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;
	import flash.display.StageScaleMode;
	
	// Sets the swf file properties, such size and framerate
	[SWF(width="500",height="130",frameRate="120",backgroundColor="#000000")]
	public class ParticleRTRunner extends Sprite
	{
		private var _oGenerator : IntervalRT;
		private var _dParticles : Dictionary;
		private var _oPauseMask : Sprite;
		
		// Our masking button is available in the *.fla file in the examples directory
		[Embed(source="../lib/example-lib.swf", symbol="PauseMask")]
		private var PauseMask : Class;
		
		public function ParticleRTRunner ()
		{
			// force the file to not be rescaled
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			_dParticles = new Dictionary();
			
			// the createParticle method will be called every 50ms
			// the interval is stopped at creation
			_oGenerator = new IntervalRT ( new Delegate ( createParticle ), 50 );
			
			// creating the mask button
			_oPauseMask = new PauseMask () as Sprite;
			_oPauseMask.alpha = .5;
			addChild( _oPauseMask );
			
			// adding listener to receive mouse events
			addEventListener( MouseEvent.MOUSE_OVER, start );
			addEventListener( MouseEvent.MOUSE_OUT, stop );
		}
		
		public function start( e : Event = null ) : void
		{
			// start or restart the particle generation
			_oGenerator.start();
			
			Mouse.hide();
			_oPauseMask.alpha = 0;
		}
		
		public function stop( e : Event = null ) : void
		{
			// stop the particle generation
			_oGenerator.stop();
			
			Mouse.show();
			_oPauseMask.alpha = .5;
		}
		
		// particles will be created by this method
		public function createParticle () : void
		{}
		
		// we also need to remove dead particles, this is done in this method
		public function removeParticle ( p : ParticleRT ) : void
		{}
	}
}
</pre></div>

<hr size="1"/>
<a name="particles"></a>
<h3>Particules</h3>

<p>
	For the moment, we just have the base code for particles generation
but we haven't any particles to generate. Particles will be as simple
as possible, and must produce all their animation in real time. To do
that, particle class extend the <code>RTObject</code> class from Kairos,
which provide many methods to work in real time with the Kairos engine.
</p><p>
	The particles class will own extra responsibilities, which will
be owned by another class in a real world project. For example we
will pass to the particle the <code>DisplayObjectContainer</code>
object onto which the particle will attach itself, as well as
a method to handle death of the particle.
</p><p>
	Our particle will look like a sparckle star. It will be composed
by a <code>Sprite</code> object containing a <code>MovieClip</code>
animation. The <code>MovieClip</code> will be animated using the
<code>MovieClipRT</code> class (you can find it in the
<a href="../../docs/com/kairos/motion/package-detail.html">
com.kairos.motion</a> package). The moves of the particles will
be performed directly by the particle class itself.
</p>

<div class="listing"><pre>
package
{
	import com.kairos.engine.RTEvent;
	import com.kairos.engine.RTObject;
	import com.kairos.motion.MovieClipRT;
	
	import flash.display.BlendMode;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.events.Event;
	
	public class ParticleRT extends RTObject
	{
		// the parent of our particle
		private var _parent : DisplayObjectContainer;
		
		// the movieclip animation of our particle
		private var _mcSprite : MovieClip;
		
		// the motion controller, which contain the movie clip
		private var _oSpriteAnimation : MovieClipRT;
		
		// required properties of the particle
		private var _x : Number;
		private var _y : Number;
		private var _speedX : Number;
		private var _speedY : Number;
		private var _life : Number;
		private var _maxLife : Number;
		
		// the "on death" callback function
		private var _onDeath : Function;
		
		// these constant are defined here, that's not the best approach, 
		// but it will do the trick
		private static const GRAVITY : Number = 98;
		private static const FRICTION : Number = .995;
		
		// the graphics of the particle, always in the *.fla file
		[Embed(source="../lib/example-lib.swf", symbol="ParticleAnimation")]
		  private var ParticleAnimation : Class;
		
		// constructor receive start values for the particle's properties
		public function ParticleRT ( parent:DisplayObjectContainer, x:Number=0, y:Number=0, speedX:Number=0, speedY:Number=0, maxLife:Number=0, scale:Number=1, onDeath:Function=null )
		{
			// particle initialization
			_x = x;
			_y = y;
			_speedX = speedX;
			_speedY = speedY;
			_life = 0;
			_maxLife = maxLife;
			_onDeath = onDeath;
			
			// creating the graphics
			_parent = parent;
			_mcSprite = new ParticleAnimation() as MovieClip;
			_mcSprite.scaleX = _mcSprite.scaleY = scale;
			_mcSprite.x = x;
			_mcSprite.y = y;
			_mcSprite.blendMode = BlendMode.ADD;
			_mcSprite.rotation = Math.floor( Math.random() * 360 ) ;
			_parent.addChild( _mcSprite );
			
			// creating the movie clip animation controller
			// animation will run at 24 fps speed
			_oSpriteAnimation = new MovieClipRT ( _mcSprite, 24 );
		}
		
		// It's in that method we will move the particle
		override public function onTick(e:Event=null):void
		{
		}
		
		// calling start on sub-entities
		override public function start():void
		{
			super.start();
			_oSpriteAnimation.start();
		}
		
		// calling stop on sub-entities   
		override public function stop():void
		{
			super.stop();
			_oSpriteAnimation.stop();
		}
	}
}
</pre></div>

<p>
	By the way, we also need to create and destroy particles in the
<code>ParticuleRTRunner</code> class.
</p>

<div class="listing"><pre>
public function createParticle () : void
{
	var p : ParticleRT = new ParticleRT( 
				 this, // particle parent
				 170, // x position at start
				 120, // y position at start
				 Math.floor( ( 100 + Math.random() * 150 ) * (1-scale/2) ),   // x speed in px/second
				 Math.floor( ( -100 - Math.random() * 100 ) * (1-scale/2) ),  // y speed in px/second
				 Math.floor( 1000 + Math.random() * 2000 ),  // lifetime of the particle, in the range 1000-3000
				 .3 + Math.random() * .7, // scale of the particle, in the range 30%-100%
				 removeParticle  // death callback function
				 );
	
	// adding the particles in the dictionary
	_dParticles[ p ] = p;
	
	// start particle animation
	p.start();
}

public function removeParticle ( p : ParticleRT ) : void
{
	p.stop();
	delete _dParticles[ p ];
}
</pre></div>

<hr size="1"/>
<a name="animation"></a>
<h3>Particles motion</h3>

<p>
	Our particles are now created by the runner, the particles' 
<code>MovieClip</code> are also animated with the <code>MovieClipRT</code>.
It remain to create the physic behavior of our particle, which is one of the
most important, and complicated task in our case. All this behavior will be
realized in the <code>onTick</code> method of the <code>ParticleRT</code> class.
Creating real time physics is more complex because we have to distinguish between
<i>state</i> values, and <i>momentum</i> values. State values are properties which are
defined for the object independtly of a momentum. More formally, the speed is a <i>state</i>, 
it was defined in pixel per second, the amount of movement of a particle in one time
is a <i>momentum</i>.
</p>

<div class="listing"><pre>
	
public override function onTick(e:Event=null):void
{
	// getting the current time step in seconds
	var stepInSeconds : Number = getLocalStepInSecond( e );
	
	//  getting the current time step in milli-seconds
	var step : Number = getLocalStep( e );
	
	// increment elapsed life time with the time step in milliseconds
	_life += step;
	
	// if elapsed life time go past maximum life time, 
	// the death callback method is called and the particle
	// is removed from its parent
	if( _life > _maxLife )
	{
		_onDeath.call( null, this );
		_parent.removeChild( _mcSprite );
		return;
	}
	
	// our particle is still alive, we need to update it
	
	// apply friction on X
	_speedX = _speedX * FRICTION;
	
	// apply friction on Y
	// as all speeds are defined in pixel per second, the gravity value
	// to apply is : gravity * time step in seconds
	_speedY = ( _speedY + ( GRAVITY * stepInSeconds ) ) * FRICTION;
	
	// same for the particle move, current move is : speed * time step in seconds
	_x += _speedX * stepInSeconds;
	_y += _speedY * stepInSeconds;
	
	// move our movie clip to the computed position
	_mcSprite.x = _x;
	_mcSprite.y = _y;
}	
</pre></div>

<p>Now, adds the pause/resume routine</p>

<div class="listing"><pre>
public function start( e : Event = null ) : void
{
	Mouse.hide();
	_oGenerator.start();
	_oPauseMask.alpha = 0;
	
	for each ( var p : ParticleRT in _dParticles )
	{
		p.start();
	}
}

public function stop( e : Event = null ) : void
{
	Mouse.show();
	_oGenerator.stop();
	_oPauseMask.alpha = .5;
	
	for each ( var p : ParticleRT in _dParticles )
	{
		p.stop();
	}
}
</pre></div>

<p>
	To add a little more fun in our demo, we will add collision between
particles and the bottom and right border of the swf file. The collision
will produce a static friction, which will reduce the speed of the particle
by two. In the <code>ParticleRT</code> class, add :
</p>

<div class="listing"><pre>
private function _collide():void
{
	if( _x > 500 )
	{
		_x = 500;
		_speedX *= -.5
	}
	
	if( _y > 130 )
	{
		_y = 130;
		_speedY *= -.5
	}
}
	</pre>
</div>

<p>The function above is called in the <code>onTick</code> method as below :</p>

<div class="listing"><pre>
override public function onTick(e:Event=null):void
{
	// getting the current time step in seconds
	var stepInSeconds : Number = getLocalStepInSecond( e );
	
	//  getting the current time step in milli-seconds
	var step : Number = getLocalStep( e );
	
	// increment elapsed life time with the time step in milliseconds
	_life += step;
	
	// if elapsed life time go past maximum life time, 
	// the death callback method is called and the particle
	// is removed from its parent
	if( _life > _maxLife )
	{
		_onDeath.call( null, this );
		_parent.removeChild( _mcSprite );
		return;
	}
	
	// our particle is still alive, we need to update it
	
	// apply friction on X
	_speedX = _speedX * FRICTION;
	
	// apply friction on Y
	// as all speeds are defined in pixel per second, the gravity value
	// to apply is : gravity * time step in seconds
	_speedY = ( _speedY + ( GRAVITY * stepInSeconds ) ) * FRICTION;
	
	// same for the particle move, current move is : speed * time step in seconds
	_x += _speedX * stepInSeconds;
	_y += _speedY * stepInSeconds;
	
	// collision with the borders
	_collide();
	
	// move our movie clip to the computed position
	_mcSprite.x = _x;
	_mcSprite.y = _y;
}		
</pre></div>

<hr size="1"/>
<a name="monitoring"></a>
<h2>Using the monitoring tools</h2>

<p>
	When building application, it's important to have a good
vision of the behavior of the application. In that context it
could be to have the amount of particles on the screen or the
recorded framerate of the swf file, in order to detect lag and
performance issues.
</p><p>
	Kairos provide a <a href="../../docs/com/kairos/utils/Monitor.html">
Monitor</a> tool, which allow to display any value to study as a curve
and as simple text. Each field in the monitor are created using objects
which implements the <code>MonitorField</code> interface (you can see it, 
and all concret fields in the <a href="../../docs/com/kairos/utils/monitor/package-detail.html">
com.kairos.utils.monitor</a> package).
</p><p>
	We will create a custom field, which will display the amount
of particles on the stage at each step of the animation.
</p>

<div class="listing"><pre>
package
{
	import com.bourre.structures.Range;
	import com.kairos.engine.RTEvent;
	import com.kairos.utils.monitor.AbstractMonitorField;
	
	import flash.utils.Dictionary;
	
	// Extending AbstractMonitorField provides all the material to create a new field
	public class ParticleRTField extends AbstractMonitorField
	{
		// the target dictionary which contains the particle
		private var _oDictionary : Dictionary;
		
		public function ParticleRTField(name : String="Untitled", target:Dictionary=null, unit:String="ms", dr:Range=null, col:Number=0xffffff)
		{
			_oDictionary = target;
			super(name, _count(), unit, dr, col);
		}
		
		// that method count how many particles there is in the dictionary
		private function _count () : Number
		{
			var n : Number = 0;
			for each( var i : * in _oDictionary )
			{
				n++;
			}       
			return n;
		}       
		
		// at each step of animation the registerValue() method is called by the monitor
		override public function registerValue(e:RTEvent):void
		{
			// registering last value
			_nLastValue = _nValue;
			
			// setting new value
			_nValue = _count();
		}
	}
}		
</pre></div>

<p>
	Now, lets create the monitor in our runner :
</p>

<div class="listing"><pre>
public function ParticleRTRunner ()
{
	// force the file to not be rescaled
	stage.scaleMode = StageScaleMode.NO_SCALE;
	
	_dParticles = new Dictionary();
	
	// the createParticle method will be called every 50ms
	// the interval is stopped at creation
	_oGenerator = new IntervalRT ( new Delegate ( createParticle ), 50 );
	
	// creating the mask button
	_oPauseMask = new PauseMask () as Sprite;
	_oPauseMask.alpha = .5;
	addChild( _oPauseMask );
	
	// creating the monitor
	_oMonitor = new Monitor ( 150, 80 );
	
	// defining its fields
	_oMonitor.addField( MonitorFieldsList.FPS );
	_oMonitor.addField( new ParticleRTField ( 
					"Particles", 
				  	_dParticles, 
				  	"particles",
				  	0xffff9900, 
				  	new Range ( 0, 100 ) ) );
	
	// addding the monitor to the stage
	addChild( _oMonitor );
	
	// adding listener to receive mouse events
	addEventListener( MouseEvent.MOUSE_OVER, start );
	addEventListener( MouseEvent.MOUSE_OUT, stop );
}
</pre></div>

<p>And, as the monitor is also an animated object, we will plug it
in our pause/resume function.</p>

<div class="listing"><pre>
public function start( e : Event = null ) : void
{
	Mouse.hide();
	_oGenerator.start();
	_oPauseMask.alpha = 0;
	_oMonitor.start();
	
	for each ( var p : ParticleRT in _dParticles )
	{
		p.start();
	}
}
public function stop( e : Event = null ) : void
{
	Mouse.show();
	_oGenerator.stop();
	_oPauseMask.alpha = .5;
	_oMonitor.stop();
	
	for each ( var p : ParticleRT in _dParticles )
	{
		p.stop();
	}
}		
</pre></div>

<hr size="1"/>
<a name="adjust"></a>
<h2>Last tweaks</h2>

<p>
	Now we have an fully animated demo, and our particules
are animated in real time, to verify that point simply change
the framerate of the swf and you will see that particles
always move at the same speed. However, if a freeze occurs, particles
will have a big gap in their movement. Such behavior can produce many
bugs in a game (an object will pass through a wall without detecting
it, etc…).
</p><p>
	To avoid these behaviors we will use two methods provided by
the <code>RTBeacon</code> class. These methods allow us to constraints
the message dispatched by the <code>RTBeacon</code> to its listeners 
(all animated objects). In the constructor of the <code>ParticleRTRunner</code>
class we will add : 
</p>

<div class="listing"><pre>
RTBeacon.getInstance().setMaxStepSize( 100 );

RTBeacon.getInstance().setSmoothness( 10 );		
</pre></div>

<p>
	The first line constraints the maximum step value transmitted
to the animated objects to <code>100</code> milliseconds. The second line create
a smooth effects by transmitting the average value of <code>10</code> last recorded
values.
</p>

<hr size="1"/>
<a name="motion"></a>
<h3>Slow/fast motion effects</h3>

<p>
	As all particles are constrained by the behavior of the <code>RTBeacon</code>
class, it is pretty easy to create a slow motion effect over all objects. Simply
use the <code>setGlobalSpeed()</code> method of the <code>RTBeacon</code> class
or the <code>setLocalSpeed()</code> method inherited from <code>RTObject</code>.
The <code>setLocalSpeed()</code> method allow time scaling on instance at the same
time than a global time scaling.
</p>

<div class="listing"><pre>
	RTBeacon.getInstance().setGlobalSpeed( .5 ); // on divise le pas transmis aux objets par 2
</pre></div>

</div>		
	</body>
</html>